import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;


/**
 * The Class VendingMachineTest used to test the VendingMachine class
 * @author Archana
 *
 */
public class VendingMachineTest {
	
	VendingMachine tstVendingMachine;
    VendingMachineItem tstMachineItem;
    
    /**
	 * set up test fixture
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		tstVendingMachine = new VendingMachine();
		tstMachineItem = new VendingMachineItem("Item1", 1.00);
	}
	
	
	/**
	 * Tear down
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
		tstVendingMachine=null;
		tstMachineItem=null;
	}

	/**
     * Test method for addItem(VendingMachineItem item,java.lang.String code)
     * Tests adding an item to the vending machine in an empty slot.
     */
	@Test
	public void tstAddItem_EmptySlot()
    {
            VendingMachineItem tstMachineItem1 = new VendingMachineItem("Item2", 2.00);
            VendingMachineItem tstMachineItem2 = new VendingMachineItem("Item3", 2.50);
            
            tstVendingMachine.addItem(tstMachineItem, tstVendingMachine.A_CODE);
            tstVendingMachine.addItem(tstMachineItem1, tstVendingMachine.B_CODE);
            tstVendingMachine.addItem(tstMachineItem2, tstVendingMachine.C_CODE);
            tstVendingMachine.addItem(tstMachineItem2, tstVendingMachine.D_CODE);

            assertEquals(tstMachineItem, tstVendingMachine.getItem(tstVendingMachine.A_CODE));
            assertEquals(tstMachineItem1, tstVendingMachine.getItem(tstVendingMachine.B_CODE));
            assertEquals(tstMachineItem2, tstVendingMachine.getItem(tstVendingMachine.C_CODE));
            assertEquals(tstMachineItem2, tstVendingMachine.getItem(tstVendingMachine.D_CODE));
    }

	
	/**
     * Test method for addItem(VendingMachineItem item,java.lang.String code)
     * Tests adding an item to the vending machine in a slot that is already occupied.
     */
    @Test(expected = VendingMachineException.class)
    public void tstAddItem_NonemptySlot()
    {
    	VendingMachineItem tstMachineItem1 = new VendingMachineItem("Item2", 2.00);

            tstVendingMachine.addItem(tstMachineItem, tstVendingMachine.A_CODE);
            tstVendingMachine.addItem(tstMachineItem1, tstVendingMachine.A_CODE);
    }



    /**
     * Test method for addItem(VendingMachineItem item,java.lang.String code)
     * Tests adding an item with an invalid code to the vending machine.
     */
    @Test(expected = VendingMachineException.class)
    public void tstAddItem_InvalidCode()
    {
            tstVendingMachine.addItem(tstMachineItem, "F");
    }
    
    /**
     * Test method for removeItem(java.lang.String).
     * Tests removing an item from the vending machine when the slot is not empty.
     */
    @Test
    public void tstRemoveItem_NonemptySlot()
    {
            tstVendingMachine.addItem(tstMachineItem, tstVendingMachine.A_CODE);

            assertEquals(tstMachineItem,
                            tstVendingMachine.removeItem(tstVendingMachine.A_CODE));
    }



    /**
     * Test method for removeItem(java.lang.String).
     * Tests removing an item from an empty slot in the vending machine.
     */
    @Test(expected = VendingMachineException.class)
    public void tstRemoveItem_EmptySlot()
    {
            tstVendingMachine.removeItem(tstVendingMachine.A_CODE);
    }



    /**
     * Test method for removeItem(java.lang.String).
     * Tests removing an item from an invalid slot in the vending machine.
     */
    @Test(expected = VendingMachineException.class)
    public void tstRemoveItem_InvalidCode()
    {
            tstVendingMachine.removeItem("F");
    }



    /**
     * Test method for insertMoney(double). 
     * Tests the insertMoney method when the amount entered < zero.
     */
    @Test(expected = VendingMachineException.class)
    public void tstInsertMoney_LessThnZero()
    {
            tstVendingMachine.insertMoney(-1);
    }



    /**
     * Test method for insertMoney(double).
     * Tests the insertMoney method when the amount entered >= zero.
     */
    @Test
    public void tstInsertMoney_GreaterThnZero()
    {
            tstVendingMachine.insertMoney(1);

            assertEquals(1, tstVendingMachine.getBalance(), 0.001);
    }



    /**
     * Test method for getBalance(). 
     * Tests the getBalance method to ensure that the vending machine starts with a 0 balance.
     */
    @Test
    public void tstGetBalance()
    {
            assertEquals(0, tstVendingMachine.getBalance(), 0.001);
    }



    /**
     * Test method for makePurchase(java.lang.String).
     * Tests the makePurchase method if there is enough money to make a purchase.
     */
    @Test
    public void tstMakePurchase_EnoughMoney()
    {
            tstVendingMachine.addItem(tstMachineItem, tstVendingMachine.A_CODE);
            tstVendingMachine.insertMoney(5);

            assertTrue(tstVendingMachine.makePurchase(tstVendingMachine.A_CODE));
            assertEquals(4, tstVendingMachine.getBalance(), 0.001);
    }



    /**
     * Test method for makePurchase(java.lang.String).
     * Tests the makePurchase method if there isn't enough money put into the vending machine to make a purchase.
     */
    @Test
    public void tstMakePurchase_NotEnoughMoney()
    {
            tstVendingMachine.addItem(tstMachineItem, tstVendingMachine.A_CODE);

            assertFalse(tstVendingMachine.makePurchase(tstVendingMachine.A_CODE));
    }



    /**
     * Test method for makePurchase(java.lang.String).
     * Tests the makePurchase method if a purchase is made for an empty slot.
     */
    @Test
    public void tstMakePurchase_EmptySlot()
    {
            assertFalse(tstVendingMachine.makePurchase(tstVendingMachine.A_CODE));
    }



    /**
     * Test method for returnChange().
     */
    @Test
    public void tstReturnChange()
    {
            tstVendingMachine.addItem(tstMachineItem, tstVendingMachine.A_CODE);
            tstVendingMachine.insertMoney(5);
            tstVendingMachine.makePurchase(tstVendingMachine.A_CODE);

            assertEquals(4, tstVendingMachine.returnChange(), 0.001);
            assertEquals(0, tstVendingMachine.getBalance(), 0.001);
    }

	
}
